/*
 * Copyright (c) 2024 endless-sky
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
#include <libavcodec/bsf.h>
}

#include <iostream>
#include <fstream>
#include <string>
#include <memory>
#include <vector>
#include <functional>
#include <thread>
#include <atomic>
#include <mutex>
#include "common_media_define.h"
#include "media_frame.h"

namespace El {
namespace Muxer {

class MP4Read {
    MP4Read(const MP4Read &) = delete;
    MP4Read &operator=(const MP4Read &) = delete;
    MP4Read(MP4Read &&) = delete;
    MP4Read &operator=(MP4Read &&) = delete;

public:
    MP4Read();
    ~MP4Read();

    bool Open(const std::string &inputFile);

    bool GetVideoInfo(VideoEncFormat &video);

    bool GetAudioInfo(AudioEncFormat &audio);

    // 获取视频总时长(毫秒)
    int64_t GetDuration() const;

    // 跳转到指定时间点(毫秒)
    bool Seek(int64_t target_ms);

    // 注册视频回调函数
    bool RegisterVideoCallback(std::function<void(const Media::MediaFramePtr &)> videoCallback);

    // 注册音频回调函数
    bool RegisterAudioCallback(std::function<void(const Media::MediaFramePtr &)> audioCallback);

    // 启动播放
    bool Start(bool loop = false);

    // 暂停播放
    bool Pause();

    // 恢复播放
    bool Resume();

    // 停止播放
    void Stop();

private:
    // 处理线程
    void ProcessingLoop();

    // 新增的私有成员函数
    void ProcessVideoPacket(AVPacket *pkt, uint64_t &total_pts);
    void ProcessAudioPacket(AVPacket *pkt, uint64_t &total_pts);

    std::vector<uint8_t> GenerateADTSHeader(int aac_data_length, int sample_rate);

    int GetFrequencyIndex(int sample_rate);

private:
    std::string input_file;
    AVFormatContext *format_ctx_raw = nullptr;
    std::unique_ptr<AVFormatContext, void (*)(AVFormatContext *)> format_ctx;

    // 视频相关
    int32_t video_stream_index = -1;
    const AVCodec *video_codec = nullptr;
    std::unique_ptr<AVCodecContext, void (*)(AVCodecContext *)> video_codec_ctx;
    std::unique_ptr<AVPacket, void (*)(AVPacket *)> video_packet;
    const AVBitStreamFilter *video_bsf = nullptr;
    AVBSFContext *video_bsf_ctx_raw = nullptr;
    std::unique_ptr<AVBSFContext, void (*)(AVBSFContext *)> video_bsf_ctx;

    // 音频相关
    int32_t audio_stream_index = -1;
    const AVCodec *audio_codec = nullptr;
    std::unique_ptr<AVCodecContext, void (*)(AVCodecContext *)> audio_codec_ctx;
    const AVBitStreamFilter *audio_bsf = nullptr;
    AVBSFContext *audio_bsf_ctx_raw = nullptr;
    std::unique_ptr<AVBSFContext, void (*)(AVBSFContext *)> audio_bsf_ctx;

    std::chrono::steady_clock::time_point video_start_time;
    std::chrono::steady_clock::time_point audio_start_time;
    bool is_first_video_frame{true};
    bool is_first_audio_frame{true};

    // 回调函数
    std::function<void(const Media::MediaFramePtr &)> video_callback;
    std::function<void(const Media::MediaFramePtr &)> audio_callback;

    // 线程控制
    std::thread processing_thread;
    std::atomic<bool> is_running{false};
    std::mutex callback_mutex;

    std::atomic<bool> should_loop{false};

    // 播放状态
    std::atomic<bool> is_paused_{false};

    // 记录最后一帧的pts时间(微秒)
    int64_t last_video_pts_{0};
    int64_t last_audio_pts_{0};
};

} // namespace Muxer
} // namespace El
